
# Detect platform

UNAME := $(shell uname -s)
MACH_TYPE := $(shell uname -m)

ifneq ($(MACH_TYPE), x86_64)
    $(error Only 64-bit platform is supported currently)
endif

# compiler settings

ifndef EIGEN_HOME
	$(error The environment variable EIGEN_HOME is not defined)
endif


WARNING_FLAGS = -Wall -Wextra -Wconversion -Wformat -Wno-unused-parameter
CPPFLAGS = -I./include -isystem $(ARMA_HOME)/include -isystem $(EIGEN_HOME)

ifeq ($(UNAME), Linux)
	CXX=g++
	CXXFLAGS = -std=c++0x -pedantic $(WARNING_FLAGS) $(CPPFLAGS)
endif
ifeq ($(UNAME), Darwin)
	CXX=clang++
	CXXFLAGS = -std=c++0x -stdlib=libc++ -pedantic $(WARNING_FLAGS) $(CPPFLAGS)
endif

CXXFLAGS += -isystem $(EIGEN_HOME)

# Intel MKL configuration

USE_MKL=yes

MKL_INC_PATH = -isystem $(MKLROOT)/include

ifeq ($(UNAME), Linux)
    MKL_LNK_PATH = -L$(MKLROOT)/../../lib/intel64 -L$(MKLROOT)/lib/intel64
	MKL_LNK = -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread
endif
ifeq ($(UNAME), Darwin)
    MKL_LNK_PATH = -L$(MKLROOT)/../../lib -L$(MKLROOT)/lib
	MKL_LNK = -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread
endif
 
ifeq ($(USE_MKL), yes)
   CXXFLAGS += $(MKL_INC_PATH) $(MKL_LNK_PATH) -DEIGEN_USE_MKL_ALL
   LNKS = $(MKL_LNK)
endif

# Testing setup

MAIN_TEST_PRE=-isystem $(GTEST_HOME)/include test/test_main.cpp
MAIN_TEST_POST=$(GTEST_HOME)/lib/libgtest.a -lpthread

# directory configuration

INC=include/gmlpp


#************************************************
#
# 	Header files 
#
#************************************************

BASE_HS = \
	$(INC)/base/config.h \
	$(INC)/base/basic_defs.h \
	$(INC)/base/basic_math.h \
	$(INC)/base/simd.h \
	$(INC)/base/arg_check.h \
	$(INC)/base/mem_op.h \
	$(INC)/base/timer.h \
	$(INC)/base/range.h \
	$(INC)/base/arma.h \
	$(INC)/base/bits/arma_base.h \
	$(INC)/base/bits/arma_reduce.h \
	$(INC)/base/bits/arma_bsxfun.h \
	$(INC)/base/bits/arma_vecmap.h \
	$(INC)/base/bits/arma_printf.h
	
CORE_HS = \
	$(INC)/core/accum.h \
	$(INC)/core/pdmat.h \
	$(INC)/core/metrics.h \
	$(INC)/core/sfmt.h \
	$(INC)/core/basic_rng.h \
	$(INC)/core/discrete_sampler.h \
	$(INC)/core/random.h
	
	
#************************************************
#
# 	Build targets 
#
#************************************************	
	
.PHONY: all	
all: test bench

.PHONY: test
test: bin/test_eigen

.PHONY: bench
bench: bin/bench_eigen_mtimes

.PHONY: clean
clean:
	rm bin/*


# ****  test_base ****

TEST_BASE_SRC = \
	test/test_arma_base.cpp

bin/test_base: $(BASE_HS) $(TEST_BASE_SRC)
	$(CXX) $(CXXFLAGS) $(MAIN_TEST_PRE) $(TEST_BASE_SRC) $(MAIN_TEST_POST) $(LNKS) -o $@
	
# **** bench base ****

bin/bench_eigen_mtimes: $(BASE_HS) bench/bench_eigen_mtimes.cpp
	$(CXX) $(CXXFLAGS) -O2 bench/bench_eigen_mtimes.cpp $(LNKS) -o $@

	
	
# ****  test_core ****

TEST_CORE_SRC = \
	test/test_pdmat.cpp
	
bin/test_core: $(BASE_HS) $(CORE_HS) $(TEST_CORE_SRC)
	$(CXX) $(CXXFLAGS) $(MAIN_TEST_PRE) $(TEST_CORE_SRC) $(MAIN_TEST_POST) $(LNKS) -o $@

	
# others	

bin/test_eigen: $(BASE_HS) test/test_eigen.cpp
	$(CXX) $(CXXFLAGS) -O3 test/test_eigen.cpp -o $@
	
bin/test_sfmt: $(BASE_HS) $(CORE_HS) test/test_sfmt.cpp
	$(CXX) $(CXXFLAGS) -O3 test/test_sfmt.cpp -o $@
	
bin/test_sfmt_icc: $(BASE_HS) $(CORE_HS) test/test_sfmt.cpp
	icpc $(CXXFLAGS_NOC11) -O3 test/test_sfmt.cpp -o $@
	
	
	
